﻿// ------------------------------------------------------------------------
//  Copyright 2025 The Dapr Authors
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//      http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//  ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using Dapr.Common;
using Autogenerated = Dapr.Client.Autogen.Grpc.v1;

namespace Dapr.AI.Conversation;

/// <summary>
/// Used to initialize a new instance of a <see cref="DaprConversationClient"/>.
/// </summary>
/// <param name="client">The Dapr client.</param>
/// <param name="httpClient">The HTTP client used by the client for calling the Dapr runtime.</param>
/// <param name="daprApiToken">An optional token required to send requests to the Dapr sidecar.</param>
[Experimental("DAPR_CONVERSATION", UrlFormat = "https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/")]
internal sealed class DaprConversationGrpcClient(Autogenerated.Dapr.DaprClient client, HttpClient httpClient, string? daprApiToken = null) : DaprConversationClient(client, httpClient, daprApiToken: daprApiToken)
{ 
    /// <inheritdoc />
    public override async Task<ConversationResponse> ConverseAsync(IReadOnlyList<ConversationInput> inputs,
        ConversationOptions options, CancellationToken cancellationToken = default)
    {
        //Configure the GRPC call options
        var grpcCallOptions = DaprClientUtilities.ConfigureGrpcCallOptions(typeof(DaprConversationClient).Assembly,
            this.DaprApiToken, cancellationToken);

        //Create the input request and emit to the runtime
        var inputRequest = ConversationProtoUtilities.CreateConversationInputRequest(inputs, options);
        var result = await Client.ConverseAlpha2Async(inputRequest, grpcCallOptions).ConfigureAwait(false);

        //Map the result back to a domain object and return
        var response = result.ToDomain();
        return response;
    }
    
    /// <inheritdoc />
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            this.HttpClient.Dispose();
        }
    }
}
